package com.feicheng.wxapi.pay;

import com.feicheng.common.exception.SystemException;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.transferbatch.TransferBatchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class WxAppPayBean {

    private String appId = "";

    private String secret = "";

//    private String payUrl = "https://46k67j4459.goho.co/";

    private String payUrl = "";

    /** 商户号 */
    private String merchantId = "";

    /** 商户API私钥内容 */
    private String privateKeyStr = "-----BEGIN PRIVATE KEY-----\n" +
            "-----END PRIVATE KEY-----\n";

    /** 商户证书序列号 */
    private String merchantSerialNumber = "";

    /** 商户APIV3密钥 */
    private String apiV3key = "";

    private JsapiServiceExtension service;

    private TransferBatchService tService;

    private RefundService rService;

    private NotificationConfig config;

    public WxAppPayBean() {
//        try {
//            config = new RSAAutoCertificateConfig.Builder()
//                    .merchantId(merchantId)
//                    .privateKey(privateKeyStr)
//                    .merchantSerialNumber(merchantSerialNumber)
//                    .apiV3Key(apiV3key).build();
//            RSAAutoCertificateConfig rsaAutoCertificateConfig = (RSAAutoCertificateConfig) config;
//            service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
//            tService = new TransferBatchService.Builder().config(rsaAutoCertificateConfig).build();
//            rService = new RefundService.Builder().config(rsaAutoCertificateConfig).build();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }


    }

    /**
     * @param outTradeNo  本地订单编号 （payment_record -> pay_id
     * @param description 描述
     * @param notifyUrl   回调地址
     * @param amount      金额
     * @param openId      客户的openId
     * @return prepayId 预支付交易单ID
     */
    public PrepayWithRequestPaymentResponse jsapi(
            String outTradeNo,
            String description,
            String notifyUrl,
            Integer amount,
            String openId) {
        try {
            // 跟之前下单示例一样，填充预下单参数
            PrepayRequest request = new PrepayRequest();

            Amount amountObj = new Amount();
            amountObj.setTotal(amount);
            request.setAmount(amountObj);
            request.setAppid(this.appId);
            request.setMchid(this.merchantId);
            request.setDescription(description);
            request.setNotifyUrl(this.payUrl + notifyUrl);
            request.setOutTradeNo(outTradeNo);
            Payer payer = new Payer();
            payer.setOpenid(openId);
            request.setPayer(payer);

            // response包含了调起支付所需的所有参数，可直接用于前端调起支付
            return service.prepayWithRequestPayment(request);
        } catch (Exception e) {
            log.error("支付失败：统一预付单失败", e);
            throw new SystemException("支付失败：统一预付单失败");
        }
    }


    public Transaction parseNotice(
            String nonce,
            String signature,
            String signatureType,
            String timestamp,
            String serial,
            String body) {
        RequestParam requestParam = new RequestParam.Builder().serialNumber(serial).nonce(nonce).signature(signature)
                .timestamp(timestamp).signType(signatureType).body(body).build();

        return new NotificationParser(config).parse(requestParam, Transaction.class);
    }

}
